package com.zhkj.crawl.rank.ext;


import cn.hutool.core.collection.CollUtil;
import com.zhkj.crawl.config.StringPool;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class NovelTest {
	private static final String HOST = "https://www.99csw.com";

	public static void main(String[] args) throws IOException {
//		List<Book> books = listCategory(Category.轻小说, 3);
		List<Book> books = listSearch("猫头鹰谋杀案");
		step(books);

	}


	private static void step(List<Book> books) throws IOException {
		DataInputStream in = new DataInputStream(System.in);

		System.out.println("选择序号：");
		int number = Integer.parseInt(in.readLine());

		Book book = books.get(number - 1);
		Book bookIndex = detail(book.id);

		System.out.println("请选择章节：");
		int idxNum = Integer.parseInt(in.readLine());

		Book.Idx idx = bookIndex.idxs.get(idxNum - 1);
		while (idx == null || StringUtils.isBlank(idx.getLink())){
			System.err.println("该章节无链接,请重新选择");
			idxNum = Integer.parseInt(in.readLine());
			idx = bookIndex.idxs.get(idxNum - 1);
		}

		getContent(idx.getLink());

		nextStep(bookIndex, idx, in);
	}

	private static void nextStep(Book book, Book.Idx idx, DataInputStream in) throws IOException {
		System.out.println("1.下一页 \t 2.上一页 \t 3.目录");
		int opt = Integer.parseInt(in.readLine());
		if(1 == opt){
			idx = book.idxs.get(idx.index);
			getContent(idx.link);
		}else if(2 == opt){
			idx = book.idxs.get(idx.index - 1);
			getContent(idx.link);
		}else if(3 == opt){
			detail(book.id);
		}
		nextStep(book, idx, in);
	}

	private static String getContent(String url) throws IOException {
		Document document = Jsoup.connect(String.format("%s%s", HOST, url))
				.get();
		String content = document.getElementById("content").text();
		System.out.println(content);
		return content;
	}


	public static List<Book> listSearch(String keyword) throws IOException {
		Document document = Jsoup.connect(String.format("%s/book/search.php?s=13139900387823019677&type=站内&q=%s", HOST, keyword))
				.get();

		return parseList(document);
	}

	private static List<Book> listCategory(Category cate, int page) throws IOException {
		Document document = Jsoup.connect(String.format("%s/book/index.php?type=%s&page=%s&size=20", HOST, cate.name(), page))
				.get();

		return parseList(document);
	}

	private static List<Book> parseList(Document document) {
		Element box = document.getElementById("list_box");
		if(box == null){
			box = document.getElementsByClass("list_box").get(0);
		}
		List<Book> books = box.select("li").stream()
				.map(s -> {
					Book book = new Book();
					Element a = s.select("a").get(0);
					String id = a.attr("href").split(StringPool.SLASH)[2];
					String name = a.attr("title");
					String auth = s.select("a").get(2).text();
					String intro = s.select(".intro").text();
					book.setId(id);
					book.setName(name);
					book.setAuth(auth);
					book.setIntro(intro);
					return book;
				}).collect(Collectors.toList());

		for (int i = 0; i < books.size(); i++) {
			System.out.printf("%s、%s\n\n", i+1, books.get(i));
		}
		return books;
	}

	public static Book detail(String id) throws IOException {
		Document document = Jsoup.connect(String.format("%s/book/%s/index.htm", HOST, id))
				.get();

		Book book = new Book();
		Elements img = document.getElementById("book_info").select("img");
		String name = img.attr("alt");
		String src = img.attr("src");

		Elements introEle = document.select(".intro");
		String intro = introEle.text();
		String auth = introEle.next("h4").select("a").stream().map(Element::text).collect(Collectors.joining(","));

		book.setId(id);
		book.setName(name);
		book.setCover(src);
		book.setIntro(intro);
		book.setAuth(auth);

		Elements ids = document.getElementById("dir").children();
		AtomicInteger i = new AtomicInteger(1);
		List<Book.Idx> idxs = ids.stream().map(s -> {
			Book.Idx idx = new Book.Idx();
			idx.setName(s.text());
			idx.setIndex(i.getAndIncrement());
			Elements a = s.getElementsByTag("a");
			if (CollUtil.isNotEmpty(a)) {
				idx.setLink(a.get(0).attr("href"));
			}
			return idx;
		}).collect(Collectors.toList());
		book.setIdxs(idxs);

		System.out.println(book);
		return book;
	}


	@Data
	public static class Book{
		private String id;
		private String name;
		private String intro;
		private String auth;
		private String cover;
		private List<Idx> idxs;

		@Data
		public static class Idx{
			private int index;
			private String name;
			private String link;
			private String content;
		}

		@Override
		public String toString() {
			StringBuilder str = new StringBuilder(String.format("《%s》(%s) - %s\n%s", name, id, auth, intro));
			if(CollUtil.isNotEmpty(idxs)){
				str.append("\n");
				for (int i = 0; i < idxs.size(); i++) {
					Idx idx = idxs.get(i);
					str.append(idx.index).append("、").append(idx.name).append("\t").append(idx.link).append("\n");
				}
			}
			return str.toString();
		}
	}

	public static enum Category{
		传记回忆,英文读本,杂文随笔,言情小说,历史小说,侦探推理,惊悚悬疑,网络玄幻,寓言童话,青春都市,社会心理,外国小说,科幻小说,
		当代小说,武侠小说,纪实报告,世界历史,中国历史,科普学习,诗歌戏曲,宗教哲学,文学理论,日语读物,作品集,国学古籍,战争军事,
		政治经济,古典文学,现代小说,官场小说,轻小说,
		;
	}
}
